-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Some more precise debug info improvements #61419
Conversation
* We were not recording precise info in inlinees except for at IL offset 0 because most of the logic that handles determining when to attach debug info did not run for inlinees. There are no changes in what the EE sees since we were normalizing debug info back to the root anyway. * Propagate debug info even further than just until rationalization, to make it simpler to dump the precise debug info. This means we create some more GT_IL_OFFSET nodes, in particular when the inlinee debug info is valid but the root info is invalid. This is currently happening for newobj IL instructions when the constructor is inlined. We generate two statements: GT_ASG(GT_LCL_VAR(X), ALLOCOBJ(CLS)); GT_CALL(CTOR, GT_LCL_VAR(X)) and the first statement ends up "consuming" the debug info, meaning we end up with no debug info for the GT_CALL, which eventually propagates into the inline tree. I have held off on fixing this for now since it causes debug info diffs in the data reported back to the EE. The additional nodes in LIR result in 0.15% more memory use and 0.015% more instructions retired for SPMI over libraries. There is also a small fix in gtlist.h for GT_BFIZ when MEASURE_NODE_SIZES is defined. No SPMI diffs.
Tagging subscribers to this area: @JulieLeeMSFT Issue Details
There is also a small fix in gtlist.h for GT_BFIZ when No SPMI diffs.
|
For using System.Runtime.CompilerServices;
public class Program
{
public static void Main()
{
System.Console.WriteLine(1);
Foo();
System.Console.WriteLine(6);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Foo()
{
System.Console.WriteLine(2);
Bar();
System.Console.WriteLine(5);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void Bar()
{
System.Console.WriteLine(3);
System.Console.WriteLine(4);
}
} we now see ***** BB01
STMT00000 ( 0x000[E-] ... 0x011 )
[000001] --C-G------- ▌ CALL void System.Console.WriteLine
[000000] ------------ arg0 └──▌ CNS_INT int 1
***** BB01
STMT00004 ( INL01 @ 0x000[E-] ... ??? ) <- INLRT @ 0x006[E-]
[000007] --C-G------- ▌ CALL void System.Console.WriteLine
[000006] ------------ arg0 └──▌ CNS_INT int 2
***** BB01
-STMT00007 ( INL02 @ 0x000[E-] ... ??? ) <- INL01 @ ??? <- INLRT @ 0x006[E-]
+STMT00007 ( INL02 @ 0x000[E-] ... ??? ) <- INL01 @ 0x006[E-] <- INLRT @ 0x006[E-]
[000013] --C-G------- ▌ CALL void System.Console.WriteLine
[000012] ------------ arg0 └──▌ CNS_INT int 3
***** BB01
-STMT00008 ( INL02 @ ??? ... ??? ) <- INL01 @ ??? <- INLRT @ 0x006[E-]
+STMT00008 ( INL02 @ 0x006[E-] ... ??? ) <- INL01 @ 0x006[E-] <- INLRT @ 0x006[E-]
[000015] --C-G------- ▌ CALL void System.Console.WriteLine
[000014] ------------ arg0 └──▌ CNS_INT int 4
***** BB01
-STMT00006 ( INL01 @ ??? ... ??? ) <- INLRT @ 0x006[E-]
+STMT00006 ( INL01 @ 0x00B[E-] ... ??? ) <- INLRT @ 0x006[E-]
[000010] --C-G------- ▌ CALL void System.Console.WriteLine
[000009] ------------ arg0 └──▌ CNS_INT int 5
***** BB01
STMT00002 ( 0x00B[E-] ... ??? )
[000004] --C-G------- ▌ CALL void System.Console.WriteLine
[000003] ------------ arg0 └──▌ CNS_INT int 6
***** BB01
STMT00003 ( 0x011[E-] ... ??? )
[000005] ------------ ▌ RETURN void and as a bonus, we get the following in LIR dump output: ------------ BB01 [000..012) (return), preds={} succs={}
- [000023] ------------ IL_OFFSET void IL offset: 0x0
+ [000023] ------------ IL_OFFSET void INLRT @ 0x000[E-]
N002 ( 1, 1) [000000] ------------ t0 = CNS_INT int 1 $41
┌──▌ t0 int arg0 in rcx
N003 ( 15, 7) [000001] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000024] ------------ IL_OFFSET void IL offset: 0x6
+ [000024] ------------ IL_OFFSET void INL01 @ 0x000[E-] <- INLRT @ 0x006[E-]
N002 ( 1, 1) [000006] ------------ t6 = CNS_INT int 2 $42
┌──▌ t6 int arg0 in rcx
N003 ( 15, 7) [000007] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000025] ------------ IL_OFFSET void IL offset: 0x6
+ [000025] ------------ IL_OFFSET void INL02 @ 0x000[E-] <- INL01 @ 0x006[E-] <- INLRT @ 0x006[E-]
N002 ( 1, 1) [000012] ------------ t12 = CNS_INT int 3 $43
┌──▌ t12 int arg0 in rcx
N003 ( 15, 7) [000013] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000026] ------------ IL_OFFSET void IL offset: 0x6
+ [000026] ------------ IL_OFFSET void INL02 @ 0x006[E-] <- INL01 @ 0x006[E-] <- INLRT @ 0x006[E-]
N002 ( 1, 1) [000014] ------------ t14 = CNS_INT int 4 $44
┌──▌ t14 int arg0 in rcx
N003 ( 15, 7) [000015] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000027] ------------ IL_OFFSET void IL offset: 0x6
+ [000027] ------------ IL_OFFSET void INL01 @ 0x00B[E-] <- INLRT @ 0x006[E-]
N002 ( 1, 1) [000009] ------------ t9 = CNS_INT int 5 $45
┌──▌ t9 int arg0 in rcx
N003 ( 15, 7) [000010] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000028] ------------ IL_OFFSET void IL offset: 0xb
+ [000028] ------------ IL_OFFSET void INLRT @ 0x00B[E-]
N002 ( 1, 1) [000003] ------------ t3 = CNS_INT int 6 $46
┌──▌ t3 int arg0 in rcx
N003 ( 15, 7) [000004] --CXG------- ▌ CALL void System.Console.WriteLine $VN.Void
- [000029] ------------ IL_OFFSET void IL offset: 0x11
+ [000029] ------------ IL_OFFSET void INLRT @ 0x011[E-]
N001 ( 0, 0) [000005] ------------ RETURN void $100 cc @dotnet/jit-contrib |
{ | ||
nxtStmtOffs = | ||
(nxtStmtIndex < info.compStmtOffsetsCount) ? info.compStmtOffsets[nxtStmtIndex] : BAD_IL_OFFSET; | ||
nxtStmtOffs = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW I've always though the logic in this bit of code was convoluted. But it looks like all that's happened here is that you removed the exclusion for inlinees?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's the only change here (it's easier to see if you check "Hide whitespace" under the review settings).
We were not recording precise info in inlinees except for at IL offset
0 because most of the logic that handles determining when to attach
debug info did not run for inlinees. There are no changes in what the
EE sees since we were normalizing debug info back to the root anyway.
Propagate debug info even further than just until rationalization, to
make it simpler to dump the precise debug info. This means we create
some more GT_IL_OFFSET nodes, in particular when the inlinee debug
info is valid but the root info is invalid. This is currently
happening for newobj IL instructions when the constructor is inlined.
We generate two statements:
GT_ASG(GT_LCL_VAR(X), ALLOCOBJ(CLS));
GT_CALL(CTOR, GT_LCL_VAR(X))
and the first statement ends up "consuming" the debug info, meaning we
end up with no debug info for the GT_CALL, which eventually propagates
into the inline tree. I have held off on fixing this for now since it
causes debug info diffs in the data reported back to the EE.
The additional nodes in LIR result in 0.15% more memory use and 0.015%
more instructions retired for SPMI over libraries.
There is also a small fix in gtlist.h for GT_BFIZ when
MEASURE_NODE_SIZES is defined.
No SPMI diffs.